package group.rober.dataform.mapper.impl;

import group.rober.dataform.exception.DataFormException;
import group.rober.dataform.model.DataForm;
import group.rober.dataform.model.DataFormElement;
import group.rober.dataform.mapper.DataFormMapper;
import group.rober.dataform.model.DataFormFilter;
import group.rober.saber.kit.DateKit;
import group.rober.saber.kit.MapKit;
import group.rober.saber.kit.StringKit;
import group.rober.saber.kit.XMLKit;
import org.apache.commons.lang3.Validate;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 使用XML文件存储DataForm实体
 * Created by tisir<yangsong158@qq.com> on 2017-05-22
 */
public class DataFormMapperXMLFileImpl implements DataFormMapper {
    private String basePath;
    private boolean versionConflictDetection = true;

    public String getBasePath() {
        return basePath;
    }

    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }

    public boolean isVersionConflictDetection() {
        return versionConflictDetection;
    }

    public void setVersionConflictDetection(boolean versionConflictDetection) {
        this.versionConflictDetection = versionConflictDetection;
    }

    public DataForm getDataForm(String pack, String formId) {
        File xmlFile = getStorageFile(pack,formId);
        if(!xmlFile.exists())return null;

        DataForm dataForm = null;
        try {
            dataForm = XMLKit.readFormFile(xmlFile,getAliasMap(),DataForm.class);
        } catch (IOException e) {
            throw new DataFormException("read error file:"+xmlFile.getAbsolutePath(),e);
        }

        return dataForm;
    }

    /**
     * 根据文件存储的包目录,模板ID,获取文件实际存储文件对象
     * @param pack
     * @param id
     * @return
     */
    protected File getStorageFile(String pack,String id){
        String fileName = id+".xml";
        String filePath = pack.replaceAll("\\.","/");
        if(!filePath.startsWith("/"))filePath = "/"+filePath;
        if(!filePath.endsWith("/"))filePath = filePath + "/";
        filePath += fileName;

        return new File(basePath+filePath);
    }

    protected Map<String,Class<?>> getAliasMap(){
        Map<String,Class<?>> aliasMap = MapKit.newHashMap();
        aliasMap.put("dataform",DataForm.class);
        aliasMap.put("element",DataFormElement.class);
        aliasMap.put("filter",DataFormFilter.class);
        aliasMap.put("validator",DataFormElement.FormElementValidator.class);
        return aliasMap;
    }

    public List<DataForm> getAllDataForms() {
        return null;
    }

    public int save(DataForm dataForm) {
        Validate.notNull(dataForm);
        Validate.notNull(dataForm.getId());

        String pack = StringKit.nvl(dataForm.getPack(),"");
        File xmlFile = getStorageFile(pack,dataForm.getId());

        //目录不存在,则创建
        File parentFile = xmlFile.getParentFile();
        if(!parentFile.exists()){
            parentFile.mkdirs();
        }

        //版本冲突检测
        DataForm existsDataForm = getDataForm(pack, dataForm.getId());
        if (existsDataForm != null) {
            if (versionConflictDetection) {
                Integer v1 = existsDataForm.getRevision();
                Integer v2 = dataForm.getRevision();
                if (v1 == null) v1 = 0;
                if (v2 == null) v2 = 0;
                if (v1 != v2) {
                    throw new DataFormException("exists version " + v1 + " and current version " + v2 + " conflict");
                }
            }else{
                //使用之前的数据
                dataForm.setRevision(existsDataForm.getRevision());
                dataForm.setCreatedTime(existsDataForm.getCreatedTime());
            }
        }
        if(dataForm.getRevision()==null){
            dataForm.setRevision(0);
        }
        dataForm.setRevision(dataForm.getRevision()+1);


        if(dataForm.getCreatedTime() == null){
            dataForm.setCreatedTime(DateKit.now());
        }
        dataForm.setUpdatedTime(DateKit.now());
        try {
            XMLKit.writeToFile(dataForm,xmlFile, getAliasMap());
            return 1;
        } catch (IOException e) {
            throw new DataFormException("error saving file:"+xmlFile.getAbsolutePath(),e);
        }
    }
}
